package com.ptl.bp.dto;

import com.ptl.bp.config.SensitiveData;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import javax.validation.constraints.*;
import java.net.URI;
import java.util.List;

import static com.ptl.bp.config.DataAccessEnum.EU_COMMISSION;
import static com.ptl.bp.config.DataAccessEnum.RIGHT;

/**
 * 电池循环性信息实体类
 * 描述：包含电池拆卸信息、备件来源、回收材料含量等循环性相关数据，符合欧盟电池法规(EU) 2023/1542要求
 */
@Data
@Schema(description = "拆卸信息（至少包括：显示电池单元位置的电池系统/包爆炸图；拆卸顺序；需要解锁的紧固技术类型和数量；拆卸所需工具；如果存在损坏部件风险的警告；使用的电池单元数量和布局）；备件零件编号和来源联系方式；安全措施（附件XIII(2b-d)）；可用灭火剂（附件VI，第A部分(9)）")
public class BatteryCircularityEntity {

    // 文档类型枚举
    public enum DocumentType {
        @Schema(description = "物料清单") BillOfMaterial,
        @Schema(description = "3D模型") Model3D,
        @Schema(description = "拆卸手册") DismantlingManual,
        @Schema(description = "移除手册") RemovalManual,
        @Schema(description = "其他手册") OtherManual,
        @Schema(description = "图纸") Drawing
    }

    // 回收材料类型枚举
    public enum RecycledMaterial {
        @Schema(description = "钴") Cobalt,
        @Schema(description = "镍") Nickel,
        @Schema(description = "锂") Lithium,
        @Schema(description = "铅") Lead
    }

    // 拆卸和移除文档信息
    @Data
    @Schema(description = "拆卸和移除文档信息")
    public static class DismantlingDocument {
        @NotNull(message = "文档类型不能为空")
        @Schema(description = "文档类型，如拆卸手册", required = true)
        private DocumentType documentType;

        @NotBlank(message = "MIME类型不能为空")
        @Schema(description = "定义互联网媒体类型以确定如何解释文档URL", required = true)
        private String mimeType;

        @NotNull(message = "文档URL不能为空")
        @Schema(description = "文档链接", required = true, format = "uri")
        private String documentURL;
    }

    // 供应商地址信息
    @Data
    @Schema(description = "供应商地址信息")
    public static class SupplierAddress {
        @NotBlank(message = "国家不能为空")
        @Schema(description = "供应商所在国家", required = true)
        private String addressCountry;

        @NotBlank(message = "街道地址不能为空")
        @Schema(description = "供应商街道地址", required = true)
        private String streetAddress;

        @NotBlank(message = "邮政编码不能为空")
        @Schema(description = "供应商邮政编码", required = true)
        private String postalCode;

    }

    // 组件信息
    @Data
    @Schema(description = "组件信息")
    public static class ComponentInfo {
        @NotBlank(message = "部件名称不能为空")
        @Schema(description = "部件名称", required = true)
        private String partName;

        @NotBlank(message = "部件编号不能为空")
        @Schema(description = "部件编号", required = true)
        private String partNumber;
    }

    // 备件供应商信息
    @Data
    @Schema(description = "备件供应商信息")
    public static class SparePartSupplier {
        @NotBlank(message = "供应商名称不能为空")
        @Schema(description = "备件供应商名称", required = true)
        private String nameOfSupplier;

        @NotNull(message = "供应商地址不能为空")
        @Schema(description = "备件供应商邮政地址", required = true)
        private SupplierAddress addressOfSupplier;

        @NotBlank(message = "供应商邮箱不能为空")
        @Pattern(regexp = "^[\\w.-]+@[\\w.-]+\\.[A-Za-z]{2,}$", message = "邮箱格式不正确")
        @Schema(description = "备件供应商邮箱地址", required = true)
        private String emailAddressOfSupplier;

        @NotNull(message = "供应商网站不能为空")
        @Schema(description = "备件供应商网站地址", required = true, format = "uri")
        private String supplierWebAddress;

        @NotEmpty(message = "组件列表不能为空")
        @Schema(description = "供应商提供的组件列表", required = true)
        private List<ComponentInfo> components;
    }

    // 回收材料含量信息
    @Data
    @Schema(description = "回收材料含量信息")
    public static class RecycledContent {
        @DecimalMin(value = "0.0", message = "消费前份额不能小于0")
        @DecimalMax(value = "100.0", message = "消费前份额不能大于100")
        @Schema(description = "来自消费前废料（制造废料，不包括循环废料）的回收材料占活性材料的份额", required = true)
        private Double preConsumerShare;

        @NotNull(message = "回收材料类型不能为空")
        @Schema(description = "回收材料类型", required = true)
        private RecycledMaterial recycledMaterial;

        @DecimalMin(value = "0.0", message = "消费后份额不能小于0")
        @DecimalMax(value = "100.0", message = "消费后份额不能大于100")
        @Schema(description = "来自消费后废料（报废废料）的回收材料占活性材料的份额", required = true)
        private Double postConsumerShare;
    }

    // 安全措施信息
    @Data
    @Schema(description = "安全措施信息")
    public static class SafetyInfo {
        @NotNull(message = "安全说明链接不能为空")
        @Schema(description = "安全措施和必要的安全说明链接", required = true, format = "uri")
        private String safetyInstructions;

        @NotEmpty(message = "灭火剂列表不能为空")
        @Schema(description = "可用灭火剂类别（A、B、C、D、K类灭火器）", required = true)
        private List<String> extinguishingAgent;
    }

    // 报废信息
    @Data
    @Schema(description = "报废信息")
    public static class EndOfLifeInfo {
        @NotNull(message = "废物预防信息不能为空")
        @Schema(description = "关于最终用户在废物预防中的角色信息", required = true, format = "uri")
        private String wastePrevention;

        @NotNull(message = "分类收集信息不能为空")
        @Schema(description = "关于最终用户在废电池分类收集中的角色信息", required = true, format = "uri")
        private String separateCollection;

        @NotNull(message = "收集信息不能为空")
        @Schema(description = "关于废电池分类收集、回收、再利用操作的信息", required = true, format = "uri")
        private String informationOnCollection;
    }

    @SensitiveData(hasAnyRole = {RIGHT, EU_COMMISSION})
    @NotEmpty(message = "拆卸和移除信息不能为空")
    @Schema(description = "拆卸和移除信息，包括：显示电池单元位置的电池系统/包爆炸图；拆卸顺序；需要解锁的紧固技术类型和数量；拆卸所需工具；如果存在损坏部件风险的警告；使用的电池单元数量和布局。BR附件XIII(2c)",required = true )
    private List<DismantlingDocument> dismantlingAndRemovalInformation;

    @SensitiveData(hasAnyRole = {RIGHT, EU_COMMISSION})
    @NotEmpty(message = "备件来源不能为空")
    @Schema(description = "备件来源联系方式。邮政地址，包括名称和品牌名称、邮政编码和地点、街道和号码、国家、电话（如果有）。BR附件XIII(2b)",required = true )
    private List<SparePartSupplier> sparePartSources;

    @NotEmpty(message = "回收材料含量不能为空")
    @Schema(description = "活性材料中来自废料的材料份额，按每个电池型号每年和每个制造工厂统计",required = true )
    private List<RecycledContent> recycledContent;

    @SensitiveData(hasAnyRole = {RIGHT, EU_COMMISSION})
    @NotNull(message = "安全措施不能为空")
    @Schema(description = "安全措施和说明还应考虑过去的负面和极端事件以及单独的电池状态和电池组成/化学数据属性",required = true )
    private SafetyInfo safetyMeasures;

    @NotNull(message = "报废信息不能为空")
    @Schema(description = "生产者或生产者责任组织应向分销商和最终用户提供的信息：关于最终用户在废物预防中的角色信息",required = true )
    private EndOfLifeInfo endOfLifeInformation;

    @DecimalMin(value = "0.0", message = "可再生材料含量不能小于0")
    @Schema(description = "可再生材料含量份额。可再生材料是由可补充的自然资源制成的材料")
    private Double renewableContent;
}